package com.hq.ims.platform.controller;

import com.hq.ims.data.annotation.UserOperationMonitor;
import com.hq.ims.data.entity.Company;
import com.hq.ims.data.entity.User;
import com.hq.ims.data.entityenum.EnumAccountStatus;
import com.hq.ims.data.service.*;
import com.hq.ims.data.utils.LocalConstant;
import com.hq.ims.data.utils.WebExpandUtils;
import com.hq.ims.data.vo.*;
import com.hq.ims.platform.busservice.PlatformOrganizationStructureBusService;
import com.hq.mybatis.base.page.RequestPage;
import com.hq.mybatis.base.page.ReturnPage;
import com.hq.utils.util.ObjectUtils;
import com.hq.utils.util.StringUtils;
import com.hq.utils.vo.ReturnVo;
import com.hq.web.annotations.GetJsonValue;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;
import java.util.Optional;

/**
 *
 */
@Api(tags = "组织架构")
@RestController
@RequestMapping(LocalConstant.SYS_TYPE_PLATFORM_URL_PREFIX + "/sys/org")
public class PlatformSysOrganizationStructureController {

    @Resource
    private PlatformOrganizationStructureBusService platformOrganizationStructureBusService;
    @Resource
    private BasePermissionMapAuthorityDepartmentService basePermissionMapAuthorityDepartmentService;
    @Resource
    private BaseCompanyService baseCompanyService;
    @Resource
    private BaseCompanyDepartmentEmployeeService baseCompanyDepartmentEmployeeService;
    @Resource
    private BaseCompanyEmployeeService baseCompanyEmployeeService;
    @Resource
    private BaseUserService baseUserService;

    //----------------------------- 获取组织机构 -----------------------------------

    @ApiOperation(value = "获取公司与子公司的分级(树结构)", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
    })
    @PostMapping(value = "/getOrgTree", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ReturnVo<List<CompanyMapstruct.CompanyTreeVo>> getOrgTree(
            @GetJsonValue(zh = "公司ID", required = false) String companyId,
            @GetJsonValue(zh = "是否显示公司部门", required = false, df = "false") Boolean isShowCompanyDepartment,
            @GetJsonValue(zh = "是否包含自身", required = false, df = "false") Boolean isIncludeOneself,
            @GetJsonValue(zh = "是否包含子级", required = false, df = "false") Boolean isInclusionChildren
    ) {
        companyId = Optional.ofNullable(companyId).orElse(WebExpandUtils.getHeadCompanyId());
        List<CompanyMapstruct.CompanyTreeVo> companyTreeVoList = platformOrganizationStructureBusService.getOrgTree(companyId, isShowCompanyDepartment, isIncludeOneself, isInclusionChildren);
        return ReturnVo.buildSuccess(companyTreeVoList);
    }

    @ApiOperation(value = "获取公司与子公司的分级(平铺)", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
    })
    @PostMapping(value = "/getOrgList", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ReturnVo<List<Company>> getOrgList(
            @GetJsonValue(zh = "公司ID") String companyId,
            @GetJsonValue(zh = "是否包含自身", required = false, df = "false") Boolean isIncludeOneself
    ) {
        List<Company> allChildrenCompanyList = baseCompanyService.getAllChildrenCompanyList(companyId, isIncludeOneself);
        return ReturnVo.buildSuccess(allChildrenCompanyList);
    }

    @ApiOperation(value = "根据公司ID获取用户(分页)", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
    })
    @PostMapping(value = "/getOrgAllUserPage", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ReturnVo<ReturnPage<UserMapstruct.UserAndCompanySimpleVo>> getOrgAllUserPage(
            @RequestBody RequestPage page,
            @GetJsonValue(required = false) String realName,
            @GetJsonValue(required = false) String companyId,
            @GetJsonValue(required = false) String companyDepartmentId
    ) {

        if (StringUtils.isNotEmpty(companyDepartmentId)) {
            //公司部门ID查询
            CompanyDepartmentEmployeeMapstruct.PageSearchVo searchVo = new CompanyDepartmentEmployeeMapstruct.PageSearchVo();
            searchVo.setCompanyDepartmentId(companyDepartmentId);
            searchVo.setRealName(realName);
            platformOrganizationStructureBusService.getDepartmentAllUserPage(page, searchVo);
        } else if (StringUtils.isNotEmpty(companyId)) {
            //公司查询
            CompanyEmployeeMapstruct.PageSearchVo searchVo = new CompanyEmployeeMapstruct.PageSearchVo();
            searchVo.setCompanyId(companyId);
            searchVo.setRealName(realName);
            platformOrganizationStructureBusService.getCompanyAllUserPage(page, searchVo);
        }
        return ReturnVo.buildSuccess(page.getReturnPage());
    }

    @ApiOperation(value = "根据公司ID获取用户(分页)", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
    })
    @PostMapping(value = "/getOrgAllUserAndStatisticsPage", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ReturnVo<ReturnPage<UserMapstruct.UserAndCompanyAndSimpleStatisticsSimpleVo>> getOrgAllUserAndStatisticsPage(
            @RequestBody RequestPage page,
            @GetJsonValue(required = false) String realName,
            @GetJsonValue(required = false) String companyId,
            @GetJsonValue(required = false) String companyDepartmentId
    ) {

        if (StringUtils.isNotEmpty(companyDepartmentId)) {
            //公司部门ID查询
            CompanyDepartmentEmployeeMapstruct.PageSearchVo searchVo = new CompanyDepartmentEmployeeMapstruct.PageSearchVo();
            searchVo.setCompanyDepartmentId(companyDepartmentId);
            searchVo.setRealName(realName);
            List<UserMapstruct.UserAndCompanySimpleVo> voList = platformOrganizationStructureBusService.getDepartmentAllUserPage(page, searchVo);
            List<UserMapstruct.UserAndCompanyAndSimpleStatisticsSimpleVo> statisticsList = platformOrganizationStructureBusService.convertUserAndCompanySimpleVoToUserAndCompanyAndSimpleStatisticsSimpleVo(voList);
            page.setRecords(statisticsList);
        } else if (StringUtils.isNotEmpty(companyId)) {
            //公司查询
            CompanyEmployeeMapstruct.PageSearchVo searchVo = new CompanyEmployeeMapstruct.PageSearchVo();
            searchVo.setCompanyId(companyId);
            searchVo.setRealName(realName);
            List<UserMapstruct.UserAndCompanySimpleVo> voList = platformOrganizationStructureBusService.getCompanyAllUserPage(page, searchVo);
            List<UserMapstruct.UserAndCompanyAndSimpleStatisticsSimpleVo> statisticsList = platformOrganizationStructureBusService.convertUserAndCompanySimpleVoToUserAndCompanyAndSimpleStatisticsSimpleVo(voList);
            page.setRecords(statisticsList);
        }
        return ReturnVo.buildSuccess(page.getReturnPage());
    }


    //----------------------------- 公司操作 -----------------------------------

    @ApiOperation(value = "创建公司", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
    })
    @UserOperationMonitor
    @PostMapping(value = "/company/add", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ReturnVo<Boolean> companyAdd(
            @GetJsonValue(zh = "父ID") String parentId,
            @GetJsonValue(zh = "公司名称") String companyName
    ) {
        baseCompanyService.addPlatformCompany(parentId, companyName);
        baseCompanyService.updateRedisAllCompany();
        return ReturnVo.buildSuccess(true);
    }

    @ApiOperation(value = "更新公司", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
    })
    @UserOperationMonitor
    @PostMapping(value = "/company/update", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ReturnVo<Boolean> companyUpdate(
            @GetJsonValue(zh = "公司ID") String companyId,
            @GetJsonValue(zh = "公司名称") String companyName
    ) {
        platformOrganizationStructureBusService.updateCompanyName(companyId, companyName);
        baseCompanyService.updateRedisAllCompany();
        return ReturnVo.buildSuccess(true);
    }

    @ApiOperation(value = "冻结公司", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
    })
    @UserOperationMonitor
    @PostMapping(value = "/company/freeze", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ReturnVo<Boolean> companyFreezeCompany(
            @GetJsonValue(zh = "公司ID") String companyId
    ) {
        platformOrganizationStructureBusService.freezeCompany(companyId);
        baseCompanyService.updateRedisAllCompany();
        return ReturnVo.buildSuccess(true);
    }

    @ApiOperation(value = "解冻公司", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
    })
    @UserOperationMonitor
    @PostMapping(value = "/company/unFreeze", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ReturnVo<Boolean> companyUnFreezeCompany(
            @GetJsonValue(zh = "公司ID") String companyId
    ) {
        platformOrganizationStructureBusService.unFreezeCompany(companyId);
        baseCompanyService.updateRedisAllCompany();
        return ReturnVo.buildSuccess(true);
    }

    @ApiOperation(value = "设置公司管理员", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
    })
    @UserOperationMonitor
    @PostMapping(value = "/company/setCompanyAdmin", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ReturnVo<Boolean> companySetCompanyAdmin(
            @GetJsonValue(zh = "公司ID") String companyId,
            @GetJsonValue(zh = "用户ID") String userId,
            @GetJsonValue(zh = "是否管理员") Boolean isAdmin
    ) {
        platformOrganizationStructureBusService.setCompanyAdmin(companyId, userId, isAdmin);
        return ReturnVo.buildSuccess(true);
    }

    @ApiOperation(value = "根据公司ID获取用户(分页)", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
    })
    @PostMapping(value = "/company/getCompanyAllUserPage", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ReturnVo<List<UserMapstruct.UserAndCompanySimpleVo>> departmentGetCompanyAllUserPagePage(
            @RequestBody RequestPage page,
            @RequestBody CompanyEmployeeMapstruct.PageSearchVo searchVo
    ) {
        List<UserMapstruct.UserAndCompanySimpleVo> departmentAllUserList = platformOrganizationStructureBusService.getCompanyAllUserPage(page, searchVo);
        return ReturnVo.buildSuccess(departmentAllUserList);
    }

    //----------------------------- 部门操作 -----------------------------------

    @ApiOperation(value = "根据部门id获取当前部门所有用户", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
    })
    @PostMapping(value = "/department/getDepartmentAllUserList", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ReturnVo<List<UserMapstruct.UserAndCompanySimpleVo>> departmentGetDepartmentAllUserList(@GetJsonValue(zh = "公司部门ID") String companyDepartmentId) {
        List<UserMapstruct.UserAndCompanySimpleVo> departmentAllUserList = platformOrganizationStructureBusService.getDepartmentAllUserList(companyDepartmentId);
        return ReturnVo.buildSuccess(departmentAllUserList);
    }

    @ApiOperation(value = "根据部门ID获取用户(分页)", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
    })
    @PostMapping(value = "/department/getDepartmentAllUserPage", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ReturnVo<List<UserMapstruct.UserAndCompanySimpleVo>> departmentGetDepartmentAllUserPage(
            @RequestBody RequestPage page,
            @RequestBody CompanyDepartmentEmployeeMapstruct.PageSearchVo searchVo
    ) {
        List<UserMapstruct.UserAndCompanySimpleVo> departmentAllUserList = platformOrganizationStructureBusService.getDepartmentAllUserPage(page, searchVo);
        return ReturnVo.buildSuccess(departmentAllUserList);
    }

    @ApiOperation(value = "创建部门", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
    })
    @UserOperationMonitor
    @PostMapping(value = "/department/add", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ReturnVo<Boolean> departmentAdd(
            @GetJsonValue(zh = "公司ID") String companyId,
            @GetJsonValue(zh = "公司部门名称") String companyDepartmentName
    ) {
        platformOrganizationStructureBusService.addDepartment(companyId, companyDepartmentName);
        return ReturnVo.buildSuccess(true);
    }

    @ApiOperation(value = "更新部门", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
    })
    @UserOperationMonitor
    @PostMapping(value = "/department/update", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ReturnVo<Boolean> departmentUpdate(
            @GetJsonValue(zh = "公司部门iD") String companyDepartmentId,
            @GetJsonValue(zh = "公司部门名称") String companyDepartmentName
    ) {
        platformOrganizationStructureBusService.updateDepartment(companyDepartmentId, companyDepartmentName);
        return ReturnVo.buildSuccess(true);
    }

    @ApiOperation(value = "删除部门", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
    })
    @UserOperationMonitor
    @PostMapping(value = "/department/del", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ReturnVo<Boolean> departmentDel(
            @GetJsonValue(zh = "公司ID") String companyId,
            @GetJsonValue(zh = "公司部门ID") String companyDepartmentId
    ) {
        return platformOrganizationStructureBusService.deleteDepartment(companyId, companyDepartmentId);
    }

    @ApiOperation(value = "获取部门的绑定的角色", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
    })
    @PostMapping(value = "/department/getBindAuthList", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ReturnVo<List<PermissionAuthortyMapstruct.PermissionAuthorityVo>> departmentGetBindAuthList(@GetJsonValue(zh = "部门ID") String companyDepartmentId) {
        List<PermissionAuthortyMapstruct.PermissionAuthorityVo> voList = platformOrganizationStructureBusService.getDepartmentBindAuthList(companyDepartmentId);
        return ReturnVo.buildSuccess(voList);
    }

    @ApiOperation(value = "绑定部门和权限", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
    })
    @PostMapping(value = "/department/bindDepartmentAuth", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ReturnVo<Boolean> departmentBindDepartmentAuth(
            @RequestBody CompanyDepartmentMapstruct.BindCompanyDepartmentAuth saveVo
    ) {
        basePermissionMapAuthorityDepartmentService.bindDepartmentAuth(saveVo);
        return ReturnVo.buildSuccess(true);
    }

    @ApiOperation(value = "设置用户是否为部门负责人", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
    })
    @UserOperationMonitor
    @PostMapping(value = "/department/setUserIsPrincipal", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ReturnVo<Boolean> departmentSetUserIsPrincipal(@RequestBody CompanyDepartmentMapstruct.SetDepartmentPrincipal saveVo) {
        baseCompanyDepartmentEmployeeService.setDepartmentUserIsPrincipal(saveVo);
        return ReturnVo.buildSuccess(true);
    }

    @ApiOperation(value = "移动用户", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
    })
    @UserOperationMonitor
    @PostMapping(value = "/department/moveUserToOtherDepartment", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ReturnVo<Boolean> departmentMoveUserToOtherDepartment(@RequestBody CompanyDepartmentEmployeeMapstruct.MoveUserVo saveVo) {
        platformOrganizationStructureBusService.moveUserToOtherDepartment(saveVo);
        return ReturnVo.buildSuccess(true);
    }

    @ApiOperation(value = "修改用户职称", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
    })
    @UserOperationMonitor
    @PostMapping(value = "/department/updateJobName", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ReturnVo<Boolean> departmentUpdateJobName(
            @GetJsonValue(zh = "用户ID") String userId,
            @GetJsonValue(zh = "部门ID") String departmentId,
            @GetJsonValue(zh = "岗位名称") String jobName
    ) {
        platformOrganizationStructureBusService.updateJobName(userId, departmentId, jobName);
        return ReturnVo.buildSuccess(true);
    }

    @ApiOperation(value = "添加用户并加入部门", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
    })
    @UserOperationMonitor
    @PostMapping(value = "/department/addUserAndJoinOrg", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ReturnVo<Boolean> departmentAddUserAndJoinOrg(@RequestBody UserMapstruct.PlatformAddUserVo saveVo) {
        platformOrganizationStructureBusService.addUserAndJoinOrg(saveVo);
        return ReturnVo.buildSuccess(true);
    }

    @ApiOperation(value = "设置用户兼岗", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
    })
    @UserOperationMonitor
    @PostMapping(value = "/department/setUserIsPartTimeJob", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ReturnVo<Boolean> departmentSetUserIsPartTimeJob(@RequestBody CompanyDepartmentMapstruct.UserJoinDepartment saveVo) {
        platformOrganizationStructureBusService.joinOrg(saveVo, true);
        return ReturnVo.buildSuccess(true);
    }

    @ApiOperation(value = "从组织中移除用户", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
    })
    @UserOperationMonitor
    @PostMapping(value = "/department/removeUser", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ReturnVo<Boolean> departmentRemoveUser(@RequestBody CompanyMapstruct.RemoveUserVo saveVo) {
        baseCompanyEmployeeService.delByUserIdAndCompanyIdAndDelOtherBus(saveVo.getUserId(), saveVo.getCompanyId());
        return ReturnVo.buildSuccess(true);
    }

    //----------------------------- 用户操作 -----------------------------------

    @ApiOperation(value = "用户管理-重置密码", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
    })
    @UserOperationMonitor
    @PostMapping(value = "/resetUserPwd", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ReturnVo<Boolean> resetUserPwd(
            @GetJsonValue(zh = "用户ID") String userId
    ) {
        baseUserService.resetPassword(userId);
        return ReturnVo.buildSuccess(true);
    }

    @ApiOperation(value = "用户管理-变更状态", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
    })
    @UserOperationMonitor
    @PostMapping(value = "/setUserAccountStatus", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ReturnVo<Boolean> setUserAccountStatus(
            @GetJsonValue(zh = "用户id") String userId
    ) {
        User user = baseUserService.getById(userId);
        ObjectUtils.isNullThrow(user, "用户不存在");
        EnumAccountStatus accountStatus = user.getAccountStatus();
        EnumAccountStatus updateAccountStatus = user.getAccountStatus();
        if (updateAccountStatus == EnumAccountStatus.Freeze) {
            updateAccountStatus = EnumAccountStatus.Normal;
        } else {
            updateAccountStatus = EnumAccountStatus.Freeze;
        }
        baseUserService.updateUserAccountStatus(userId, updateAccountStatus);
        return ReturnVo.buildSuccess(true);
    }

    @ApiOperation(value = "强制变更用户信息", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
    })
    @PostMapping(value = "/forceChangeUserInfo", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ReturnVo<Boolean> forceChangeUserInfo(
            @RequestBody UserMapstruct.ChangeUserInfoVo userVo
    ) {
        baseUserService.updateUserInfo(userVo);
        return ReturnVo.buildSuccess(true);
    }

    @ApiOperation(value = "获取用户详情", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
    })
    @PostMapping(value = "/getByUserId", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ReturnVo<UserMapstruct.UserVo> getByUserId(
            @GetJsonValue String userId
    ) {
        User user = baseUserService.getById(userId);
        UserMapstruct.UserVo userVo = UserMapstruct.INSTANCE.toUserVo(user);
        return ReturnVo.buildSuccess(userVo);
    }


}
